#include <iostream>
#include <math.h>
#include <conio.h>
using namespace std;

class BuiltIn{
    public:
    BuiltIn(){
        srand(time(0));
    }

    int rnd(){
        return rand();
    }
};

class AdditiveRND{
    unsigned int y[56];
    public:

    AdditiveRND(){
        int k;
        srand(time(0));
        for(k=1;k<=55;k++)
        y[k]=rand()*rand();
    }

    int rnd(){
        unsigned int m=2147483648U;
        static int j=24,k=55;
        int s;
        y[k]=(y[k]+y[j])%m;
        s=y[k];
        j--; k--;
        if(j==0) j=55;
        if(k==0) k=55;
        return s;
    }
};

class ParkMiller{
    int seed;

    public:
    ParkMiller(){
        seed = 1;
    }

    unsigned int rnd(void){
        unsigned int hi,lo;
        lo=16807*(seed & 0xFFFF);
        hi=16807*(seed >> 16);
        lo+=(hi & 0x7FFF)<<16;
        lo+=hi>>15;
        if(lo>0x7FFFFFFF) lo-=0x7FFFFFFF;
        return seed=(int)lo;
    }
};
#define LOOPS 1000


int main(void){
    float v=0.0, vSum=0, vLow=9999999.9, vHigh=0.0;
    float vAll[LOOPS];

//    AdditiveRND myRandom;
//    ParkMiller myRandom;
    BuiltIn myRandom;

    for(int j=0; j<LOOPS; j++){
        int keeper[6] = {0};
        for(int i=0; i<1200; i++)
            keeper[myRandom.rnd()%6]++;
        for(int i=0; i<6; i++)
            v += (pow((keeper[i] - 200), 2)) / 200;
        vSum+=v;
        if(v>vHigh) vHigh = v;
        if(v<vLow) vLow = v;
        vAll[j] = v;
        v = 0.0;
    }

    int punishPoints = 0;
    float width = vHigh - vLow;
    for(int i=0;i<LOOPS;i++){
        float c = (vAll[i] - vLow) / width; // Ger p
        if(c < 0.01 || c > 0.99) punishPoints++;
        if(c < 0.02 || c > 0.95) punishPoints++;
        if(c < 0.10 || c > 0.90) punishPoints++;
    }


    cout << endl << "v average = " << vSum/LOOPS << endl;
    cout << "vHigh: " << vHigh << ", vLow: "<< vLow << endl;
    cout << "Punishment point: " << punishPoints << endl;

    return 0;
}
